package com.fight.util;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.client.params.ClientPNames;


/**
* @ClassName: HttpClientUtil
* @Description: TODO(httpclient模拟http请求)
* @author: 阮启伟
* @company: 上海势航网络科技有限公司
* @date 2016年5月26日 上午10:36:18
*/
public class HttpClientUtil {
	
	  private static final Log log = LogFactory.getLog(HttpClientUtil.class);
	
    //设置请求超时10秒钟 根据业务调整
    private final static int SOCKET_TIMEOUT = 10*1000;
    //设置等待数据超时时间10秒钟 根据业务调整
    private final static int CONNECTION_TIMEOUT = 10*1000;
    //如果这个参数没有被设置，默认等于CONNECTION_TIMEOUT，因此一定要设置
   //该值就是连接不够用的时候等待超时时间，一定要设置，而且不能太大 ()
    private final static Long CONN_MANAGER_TIMEOUT = 500L; 
    // 每个HOST的最大连接数量
    private final static int MAX_CONN_PRE_HOST = 20;
    // 连接池的最大连接数
    private final static int MAX_CONN = 60;
    // 连接池
    private final static HttpConnectionManager httpConnectionManager;
    static {
        httpConnectionManager = new MultiThreadedHttpConnectionManager();
        HttpConnectionManagerParams params = httpConnectionManager.getParams();
        params.setConnectionTimeout(CONNECTION_TIMEOUT);
        params.setSoTimeout(SOCKET_TIMEOUT);
        params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT, CONN_MANAGER_TIMEOUT);
        params.setDefaultMaxConnectionsPerHost(MAX_CONN_PRE_HOST);
        params.setMaxTotalConnections(MAX_CONN);
    }

   /**
    * @Title: loadHttpRequest
    * @Description: TODO(httpClient请求状态码为200进行读取)
    * @param @param post
    * @param @param responseCharsetName
    * @param @return
    * @param @throws HttpException
    * @param @throws IOException    设定文件
    * @return String    返回类型
    * @author: 阮启伟
    * @date 2016年1月5日 上午10:35:13
    * @throws
    */
    public static String loadHttpRequest(PostMethod post, String responseCharsetName) throws HttpException, IOException {
        HttpClient httpClient = new HttpClient(httpConnectionManager);
        String result = null;
        try {
        	int code =httpClient.executeMethod(post);
        	if(code==HttpStatus.SC_OK){
        		//读取为 InputStream，在网页内容数据量大时候推荐使用
        		result = new String(WebUtil.readInputStream(post.getResponseBodyAsStream()), responseCharsetName);
        	}
        } finally {
            post.releaseConnection();
        }
        return result;
    }
    
    /**
    * @Title: doHttpGetRequest
    * @Description: TODO(get请求)
    * @param @param url
    * @param @return    设定文件
    * @return String    返回类型
    * @author: 阮启伟
    * @date 2016年5月26日 上午10:37:52
    * @throws
    */
    public static String doHttpGetRequest(String url){
    	    HttpClient httpClient = new HttpClient(httpConnectionManager);
    	    /* 2 生成 GetMethod 对象并设置参数 */
    	    GetMethod getMethod = new GetMethod(url);
    	    // 设置请求重试处理，用的是默认的重试处理：请求三次
    	   getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,	new DefaultHttpMethodRetryHandler());
    	    String response = "";
    	    /* 3 执行 HTTP GET 请求 */
    	    try {
    	      int statusCode = httpClient.executeMethod(getMethod);
    	      /* 4 判断访问的状态码 */
    	      if (statusCode != HttpStatus.SC_OK) {
    	    	  log.info("请求出错: "+ getMethod.getStatusLine());
    	      }
    	      /* 5 处理 HTTP 响应内容 */
    	      // HTTP响应头部信息，这里简单打印
    	      Header[] headers = getMethod.getResponseHeaders();
    	      for (Header h : headers)
    	    	  log.info(h.getName() + "------------ " + h.getValue());
    	      // 读取 HTTP 响应内容，这里简单打印网页内容(适合网页内容数据量小)
    	     // byte[] responseBody = getMethod.getResponseBody();// 读取为字节数组
    	      //读取为 InputStream，在网页内容数据量大时候推荐使用
    	      response = new String(WebUtil.readInputStream(getMethod.getResponseBodyAsStream()),"utf-8");
    	    } catch (HttpException e) {
    	      // 发生致命的异常，可能是协议不对或者返回的内容有问题
    	    	log.info("请检查输入的URL!");
    	      e.printStackTrace();
    	    } catch (IOException e) {
    	      // 发生网络异常
    	    	log.info("发生网络异常!");
    	      e.printStackTrace();
    	    } finally {
    	      /* 6 .释放连接 */
    	      getMethod.releaseConnection();
    	    }
    	    return response;
    }
    /**
	* @Title: sendHttpRequest
	* @Description: TODO(传入url 与参数发送http请求)
	* @param @param url
	* @param @param nameValuePairs
	* @param @return
	* @param @throws HttpException
	* @param @throws IOException    设定文件
	* @return String    返回类型
	* @author: 阮启伟
	* @date 2016年3月14日 下午3:09:25
	* @throws
	*/
	public static String doHttpPostRequest(String url, NameValuePair...  nameValuePairs) throws Exception {
         HttpClient httpClient = new HttpClient(httpConnectionManager);
         String result = null;
         PostMethod post = null;
         try {
        	post = new PostMethod(url);
        	post.setRequestBody(nameValuePairs);
        	post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");// 在头文件中设置转码
		    post.setRequestHeader("Connection", "close");
         	int code =httpClient.executeMethod(post);
         	if(code==HttpStatus.SC_OK){
         		 //读取为 InputStream，在网页内容数据量大时候推荐使用
         		result = new String(WebUtil.readInputStream(post.getResponseBodyAsStream()),"utf-8");
         	}
         }catch (HttpException e) {
   	      // 发生致命的异常，可能是协议不对或者返回的内容有问题
   	    	log.info("请检查输入的URL!："+e.getMessage());
   	      e.printStackTrace();
   	    } catch (IOException e) {
   	      // 发生网络异常
   	    log.info("发生网络异常!："+e.getMessage());
   	      e.printStackTrace();
   	    } 
         finally {
        	//释放连接
             post.releaseConnection();
         }
         return result;
     }
}
